#import <Foundation/Foundation.h>
#import <objc/runtime.h>
#import <EventKit/EKRecurrenceRule.h>

#import "framework/FWCommon.h"

#import "PIRecurrance.h"


@implementation PIRecurrance


// ******************************************************************************************
#pragma mark -
#pragma mark Initialisation and object management


+ (PIRecurrance*)recurranceWithRule:(EKRecurrenceRule*)newRule
{
    PIRecurrance* item = [[[PIRecurrance alloc] init] autorelease];
    
    item->rule = [newRule retain];
    item->fromDate = PIRecurranceFromDateNone;
    
    return item;
}

+ (PIRecurrance*)recurranceWithRule:(EKRecurrenceRule*)newRule fromDate:(PIRecurranceFromDateType)newFromDate
{
    PIRecurrance* item = [[[PIRecurrance alloc] init] autorelease];
    
    item->rule = [newRule retain];
    item->fromDate = newFromDate;
    
    return item;
}

- (void)dealloc
{
    [rule release];
    
    [super dealloc];
}


// ******************************************************************************************
#pragma mark -
#pragma mark Describing the recurrance

- (NSString*)intervalDescription
{
    return [self intervalDescriptionWithWeekendStart:FWWeekdayNameUnknown];
}

- (NSString*)intervalDescriptionWithWeekendStart:(FWWeekdayName)weekendStart
{
    NSBundle* bundle = [NSBundle bundleForClass:[self class]];


    NSMutableString* recurrance = [NSMutableString stringWithCapacity:100];
        
    NSMutableString* frequency = [NSMutableString stringWithCapacity:50];
    switch (rule.frequency) {
        case EKRecurrenceFrequencyDaily:
            if (rule.interval == 1)
                [frequency appendString:localize(bundle, @"Frequency/Day")];
            else
                [frequency appendFormat:localize(bundle, @"Frequency/Days"), rule.interval];
            break;
        case EKRecurrenceFrequencyWeekly:
            if (rule.interval == 1)
                [frequency appendString:localize(bundle, @"Frequency/Week")];
            else
                [frequency appendFormat:localize(bundle, @"Frequency/Weeks"), rule.interval];
            break;
        case EKRecurrenceFrequencyMonthly:
            if (rule.interval == 1)
                [frequency appendString:localize(bundle, @"Frequency/Month")];
            else
                [frequency appendFormat:localize(bundle, @"Frequency/Months"), rule.interval];
            break;
        case EKRecurrenceFrequencyYearly:
            if (rule.interval == 1)
                [frequency appendString:localize(bundle, @"Frequency/Year")];
            else
                [frequency appendFormat:localize(bundle, @"Frequency/Years"), rule.interval];
            break;
    }
    
    NSDateFormatter* formatter = [[NSDateFormatter alloc] init];
    formatter.timeZone = [NSTimeZone systemTimeZone];
    
    BOOL weekendDays = NO;
    BOOL weekDays = NO;
    NSMutableString* each = [NSMutableString stringWithCapacity:80];
    if (rule.daysOfTheWeek) {
        NSArray* weekdays = rule.daysOfTheWeek.count > 2 ? formatter.shortWeekdaySymbols : formatter.weekdaySymbols;
        BOOL weekendDay = NO;
        BOOL weekDay = NO;
        
        for (EKRecurrenceDayOfWeek* day in rule.daysOfTheWeek) {
            [each appendString:[weekdays objectAtIndex:day.dayOfTheWeek - 1] withSeparator:@", "];
            
            // Check if we have a weekday or a weekend day
            if (weekendStart != FWWeekdayNameUnknown) {
                FWWeekdayName localDay = FWRecurranceWeekdayName(day.dayOfTheWeek);
                if ((localDay == weekendStart) || (localDay == (weekendStart + 1)))
                    weekendDay = YES;
                else
                    weekDay = YES;
            }
        }
        
        weekDays = weekDay && !weekendDay && (rule.daysOfTheWeek.count == 5);
        weekendDays = weekendDay && !weekDay && (rule.daysOfTheWeek.count == 2);
    }

    [formatter release];

    if (frequency.length > 0) {
        [recurrance appendString:frequency];
        if (weekDays)
            recurrance = [NSMutableString stringWithFormat:localize(bundle, @"Frequency/On Weekdays"), recurrance];
        else if (weekendDays)
            recurrance = [NSMutableString stringWithFormat:localize(bundle, @"Frequency/On Weekends"), recurrance];
        else if (each.length > 0)
            recurrance = [NSMutableString stringWithFormat:localize(bundle, @"Frequency/On Days"), recurrance, each];
    }
    else if (each.length > 0)
        [recurrance appendString:each];
    
    if (fromDate == PIRecurranceFromDateDueDate)
        recurrance = [NSMutableString stringWithFormat:localize(bundle, @"Frequency/From Due Date"), recurrance];
    else if (fromDate == PIRecurranceFromDateCompletionDate)
        recurrance = [NSMutableString stringWithFormat:localize(bundle, @"Frequency/From Completion"), recurrance];

#ifdef DEVELOPMENT_MODE
    [recurrance appendFormat:@"\n%@", [rule description]];
#endif
    
    return recurrance;
}

- (NSString*)untilDescription
{
    NSBundle* bundle = [NSBundle bundleForClass:[self class]];

    if (!rule.recurrenceEnd)
        return nil;
    
    if (rule.recurrenceEnd.endDate)
        return [NSString stringWithFormat:localize(bundle, @"Frequency/End/Date"),
                FWLocalDateStringForUTCDate(rule.recurrenceEnd.endDate, FWDateFormatterLongFormat, NO, bundle)];
    
    if (rule.recurrenceEnd.occurrenceCount == 1)
        return localize(bundle, @"Frequency/End/Instance");
    
    NSInteger count = rule.recurrenceEnd.occurrenceCount;
    if (count > 0)
        return [NSString stringWithFormat:localize(bundle, @"Frequency/End/Instances"), count];

    return nil;
}

// ******************************************************************************************
#pragma mark -
#pragma mark Debugging functions

- (NSString*)description
{
    return [NSString stringWithFormat:
            @"<%@: %p;"
            " fromDate = %d;",
            " recurrance = %@>",
            [self class],
            self,
            fromDate,
            rule];
}

@end
